package com.sz.netty.util;

import lombok.extern.slf4j.Slf4j;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;

/**
 * Utility class for calculating message TTL based on start time
 */
@Slf4j
public class MessageTtlCalculator {
    
    /**
     * Calculate TTL (Time To Live) in milliseconds for a message based on its start time
     * 
     * Rules:
     * - If start time is before 12:00 PM, expiration is today at 23:59:59
     * - If start time is at or after 12:00 PM, expiration is tomorrow at 23:59:59
     * 
     * @param startTime the start time of the message
     * @return TTL in milliseconds, or null if calculation fails
     */
    public static Long calculateTtlInMillis(Date startTime) {
        try {
            if (startTime == null) {
                log.warn("Start time is null, cannot calculate TTL");
                return null;
            }
            
            // Convert to LocalDateTime for easier manipulation
            LocalDateTime startDateTime = startTime.toInstant()
                    .atZone(java.time.ZoneId.systemDefault())
                    .toLocalDateTime();
            
            // Get the date part of the start time
            LocalDate startDate = startDateTime.toLocalDate();
            
            // Determine cutoff time (12:00 PM)
            LocalTime cutoffTime = LocalTime.of(12, 0, 0);
            
            // Determine expiration date
            LocalDate expirationDate;
            if (startDateTime.toLocalTime().isBefore(cutoffTime)) {
                // Before 12:00 PM, expires today at 23:59:59
                expirationDate = startDate;
            } else {
                // At or after 12:00 PM, expires tomorrow at 23:59:59
                expirationDate = startDate.plusDays(1);
            }
            
            // Set expiration time to 23:59:59
            LocalDateTime expirationDateTime = expirationDate.atTime(23, 59, 59);
            
            // Calculate difference in milliseconds
            long ttlMillis = java.time.Duration.between(startDateTime, expirationDateTime).toMillis();
            
            // Ensure TTL is positive
            if (ttlMillis <= 0) {
                log.warn("Calculated TTL is non-positive: {}, returning 1 hour as default", ttlMillis);
                return 60 * 60 * 1000L; // 1 hour default
            }
            
            log.debug("Calculated TTL for start time {}: {} ms (expires at {})", 
                    startDateTime, ttlMillis, expirationDateTime);
            
            return ttlMillis;
        } catch (Exception e) {
            log.error("Error calculating TTL for start time: {}", startTime, e);
            return null;
        }
    }
    
    /**
     * Format TTL milliseconds to a human-readable string
     * 
     * @param ttlMillis TTL in milliseconds
     * @return formatted string (e.g., "2h 30m 15s")
     */
    public static String formatTtl(Long ttlMillis) {
        if (ttlMillis == null) {
            return "null";
        }
        
        long seconds = ttlMillis / 1000;
        long hours = seconds / 3600;
        long minutes = (seconds % 3600) / 60;
        long secs = seconds % 60;
        
        return String.format("%dh %dm %ds", hours, minutes, secs);
    }
}